package com.link.base.tencent.corpwx.agent.service;

import com.alibaba.fastjson.JSONObject;
import com.link.base.tencent.corpwx.agent.dao.mybatis.mapper.AgentMapper;
import com.link.base.tencent.corpwx.agent.model.Agent;
import com.link.base.tencent.corpwx.agent.util.AgentTokenUtil;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.PasswordUtil;
import com.link.core.util.RedisUtil;
import com.link.core.util.redisclient.LinkRedisClient;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 应用access_token服务
 *
 * @author 欧阳振强
 * @date 2019/1/2
 */
@Service
public class AgentServiceImpl extends BasicServiceImpl<Agent> implements AgentService {
    /**
     * 应用token前缀 - redisKey
     */
    private static final String TOKEN_REDIS_KEY = "corp_wx_agent_token_";
    /**
     * 企业jsTicket前缀 - redisKey
     */
    private static final String TICKET_REDIS_KEY = "corp_wx_js_ticket_";
    /**
     * 第三方应用jsTicket前缀 - redisKey
     */
    private static final String AGENT_TICKET_REDIS_KEY = "corp_wx_agent_js_ticket_";
    /**
     * token/jsTicket有效期
     */
    private static final int EXPIRE_TIME = 7200;


    @Resource
    private AgentMapper agentMapper;

    @Override
    public BasicMapper<Agent> getBasicMapper() throws Exception {
        return agentMapper;
    }

    @Override
    public Agent queryAgentByName(Agent record) throws Exception {
        if (StringUtils.isBlank(record.getAgentName())) {
            throw new BasicServiceException("请传入应用名称！");
        }
        List<Agent> list = agentMapper.queryByExamplePage(record);
        Agent result = new Agent();
        if (list != null && list.size() > 0) {
            result = list.get(0);
        }
        return result;
    }

    @Override
    public Agent queryAgentById(Agent record) throws Exception {
        if (StringUtils.isBlank(record.getAgentId())) {
            throw new BasicServiceException("请传入AgentId！");
        }
        return agentMapper.queryAgentById(record);
    }

    @Override
    public void refreshAllTokenByAgentId() throws Exception {
        List<Agent> list = agentMapper.getCorpWxAppList();
        if (list != null) {
            LinkRedisClient j = null;
            try {
                j = RedisUtil.getJedis();
                for (Agent item : list) {
                    String wxCorpId = item.getWxCorpId();
                    String agentId = item.getAgentId();
                    String secret = item.getSecret();
                    String accessToken = AgentTokenUtil.getAccessToken(wxCorpId, secret);
                    j.set(TOKEN_REDIS_KEY + agentId, accessToken);
                    j.expire(TOKEN_REDIS_KEY + agentId, EXPIRE_TIME);
                }
            } finally {
                RedisUtil.returnResource(j);
            }
        }
    }

    @Override
    public String refreshAgentTokenByAgentId(String agentId) throws Exception {
        if (StringUtils.isBlank(agentId)) {
            throw new BasicServiceException("agentId不能为空！");
        }
        Agent agent = new Agent();
        agent.setAgentId(agentId);
        Agent result = agentMapper.getCorpWxAppItem(agent);
        if (result == null) {
            throw new BasicServiceException("未匹配到有效应用信息【agentId => " + agentId + "】");
        }
        //result.getWxCorpId()
        String wxCorpId = result.getWxCorpId();
        String secret = result.getSecret();
        String accessToken = AgentTokenUtil.getAccessToken(wxCorpId, secret);
        LinkRedisClient j = null;
        try {
            j = RedisUtil.getJedis();
            j.set(TOKEN_REDIS_KEY + agentId, accessToken);
            j.expire(TOKEN_REDIS_KEY + agentId, EXPIRE_TIME);
        } finally {
            RedisUtil.returnResource(j);
        }
        return accessToken;
    }

    @Override
    public String getExistAccessToken(String agentId) throws Exception {
        if (StringUtils.isBlank(agentId)) {
            throw new BasicServiceException("agentId不能为空！");
        }
        String accessTokenNow;
        LinkRedisClient j = null;
        try {
            j = RedisUtil.getJedis();
            accessTokenNow = j.get(TOKEN_REDIS_KEY + agentId);
            if (StringUtils.isBlank(accessTokenNow)) {
                accessTokenNow = this.refreshAgentTokenByAgentId(agentId);
            }
        } finally {
            RedisUtil.returnResource(j);
        }
        return accessTokenNow;
    }

    @Override
    public String getExistJsTicket(String agentId) throws Exception {
        if (StringUtils.isBlank(agentId)) {
            throw new BasicServiceException("agentId不能为空！");
        }
        String jsTicketNow;
        LinkRedisClient j = null;
        try {
            j = RedisUtil.getJedis();
            jsTicketNow = j.get(TICKET_REDIS_KEY + agentId);
            if (StringUtils.isBlank(jsTicketNow)) {
                jsTicketNow = AgentTokenUtil.getJsTicket(this.getExistAccessToken(agentId));
                j.set(TICKET_REDIS_KEY + agentId, jsTicketNow);
                j.expire(TICKET_REDIS_KEY + agentId, EXPIRE_TIME);
            }
        } finally {
            RedisUtil.returnResource(j);
        }
        return jsTicketNow;
    }

    @Override
    public String getExistAgentJsTicket(String agentId) throws Exception {
        if (StringUtils.isBlank(agentId)) {
            throw new BasicServiceException("agentId不能为空！");
        }
        String jsTicketNow;
        LinkRedisClient j = null;
        try {
            j = RedisUtil.getJedis();
            jsTicketNow = j.get(AGENT_TICKET_REDIS_KEY + agentId);
            if (StringUtils.isBlank(jsTicketNow)) {
                jsTicketNow = AgentTokenUtil.getAgentJsTicket(this.getExistAccessToken(agentId));
                j.set(AGENT_TICKET_REDIS_KEY + agentId, jsTicketNow);
                j.expire(AGENT_TICKET_REDIS_KEY + agentId, EXPIRE_TIME);
            }
        } finally {
            RedisUtil.returnResource(j);
        }
        return jsTicketNow;
    }

    @Override
    public JSONObject getSessionKey(String corpId, String code) throws Exception {
        if (StringUtils.isBlank(corpId)) {
            throw new BasicServiceException("应用id不能为空不能为空！");
        }
        if (StringUtils.isBlank(code)) {
            throw new BasicServiceException("code不能为空！");
        }

        String accessToken = getExistAccessToken(corpId);
        return AgentTokenUtil.codeToSessionOfMp(accessToken, code);
    }

    @Override
    public void cacheSessionKey(JSONObject userIdSession) {
        LinkRedisClient j = RedisUtil.getJedis();
        String username = userIdSession.getString("userid");
        String sessionKey = userIdSession.getString("session_key");
        String session_key = PasswordUtil.md5(new Date() + username);
        j.hset(session_key, "username", username);
        j.hset(session_key, "sessionKey", sessionKey);
        j.expire(session_key, 7200);
    }
}
